package cn.runagain.demo.xianliu;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 计数器限流实现
 * <p>
 * 时间片思想，在一段时间内，对方法调用进行统计，
 * 对阈值进行比较，决定是否放行，到达时间临界点计数器清零
 * <p>
 * 时间片的缺点在于在临界点的突发大量请求，可能会导致大量请求打到系统，极端情况下恶意请求甚至会超过系统预期的承受
 * <p>
 * created by
 *
 * @author tuxianchao
 * @date 2018/6/16 下午11:54
 */
public class CountDemo {
    private static long timeStamp = System.currentTimeMillis();
    //限制1s内100个请求
    private static long limitCount = 100;
    private static long interval = 1000;

    //当前时间片请求数
    private static long requestCount = 0;

    public static boolean grant() {
        long now = System.currentTimeMillis();
        if (now < timeStamp + interval) {
            //时间片内
            if (requestCount < limitCount) {
                //do
                requestCount++;
                return true;
            } else {
                //限流
                return false;
            }
        } else {
            //时间片结束，清0
            timeStamp = System.currentTimeMillis();
            requestCount = 0;
            return false;
        }
    }

    public static void main(String[] args) {
        AtomicInteger c = new AtomicInteger();
        c.set(1);
        AtomicInteger d = new AtomicInteger();
        d.set(1);

        for (int i = 0; i < 1000; i++) {
            new Thread(() -> {
                if (grant()) {
                    System.out.println("执行业务逻辑..." + (c.getAndIncrement()));
                } else {
                    System.out.println("限流处理..." + (d.getAndIncrement()));
                }
            }).start();
        }
    }

}
